﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.IO;

using iPdf.Properties;
using Elegant.Ui;

namespace iPdf
{
    abstract class ImagesGallery: Gallery
    {
        #region Fields
        private static FileFormat format = FileFormat.Images;
        private static int maxRecentImageFilesCount = 9;
        private Elegant.Ui.Button BrowseImagesButton;
        protected Elegant.Ui.GalleryItemCategory BuiltInCategory =
            new Elegant.Ui.GalleryItemCategory("BuiltInWatermarkImages", "Built-In", false, true, 
                            Resources.BuiltInImagesCategory);
        protected Elegant.Ui.GalleryItemCategory RecentCategory =
            new Elegant.Ui.GalleryItemCategory("RecentWatermarkImages", "Recently Used", true, true, 
                            Resources.RecentImagesCategory);

        #endregion

        #region Properties

        protected abstract string RecentImagesDir
        {
            get;
        }

        protected int RecentImagesCount
        {
            get
            {
                int count = 0;
                foreach (GalleryItem item in this.Items)
                {
                    if (item.CategoryName == RecentCategory.Name)
                    {
                        ++count;
                    }
                }

                return count;
            }
        }

        public System.Drawing.Image SelectedImage
        {
            get
            {
                return ExtractImageFromItem(this.SelectedItem);
            }
        }

        public System.Drawing.Image HoveredImage
        {
            get
            {
                return ExtractImageFromItem(this.HoveredItem);
            }
        }

        #endregion

        #region Ctor
        public ImagesGallery()
        {
            this.MaximumItemsInRowCount = 3;
            this.MinimumItemsInRowCount = 1;
            this.PopupMinimumItemsInRowCount = 4;
            this.ItemWidth = 80;
            this.ItemHeight = 60;

            this.ItemContentPadding = new System.Windows.Forms.Padding(6);
            if (Elegant.Ui.Control.IsInDesignMode)
            {
                return;
            }

            InitializeItemCategories();
            InitializePopupItems();
        }
        #endregion

        #region Methods

        protected void InitializeItemCategories()
        {
            this.ItemCategories.AddRange(new 
                Elegant.Ui.GalleryItemCategory[] {
                BuiltInCategory, RecentCategory
            });
        }

        protected void InitializePopupItems()
        {
            this.BrowseImagesButton = new Elegant.Ui.Button();
            this.BrowseImagesButton.Id = "d8e63897-3921-4ab6-b17a-e846e00822d5";
            this.BrowseImagesButton.LargeImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
            new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.BrowseImage)});
            this.BrowseImagesButton.Location = new System.Drawing.Point(0, 0);
            this.BrowseImagesButton.Name = "BrowseImagesButton";
            this.BrowseImagesButton.Size = new System.Drawing.Size(138, 23);
            this.BrowseImagesButton.SmallImages.Images.AddRange(new Elegant.Ui.ControlImage[] {
            new Elegant.Ui.ControlImage("Normal", global::iPdf.Properties.Resources.BrowseImage16)});
            this.BrowseImagesButton.TabIndex = 3;
            this.BrowseImagesButton.Text = "Browse Images";
            this.BrowseImagesButton.Click += new EventHandler(BrowseImagesButton_Click);

            this.Popup.Items.AddRange(new System.Windows.Forms.Control[] {
            this.BrowseImagesButton});
        }

        public void Load()
        {
            LoadBuiltInImages();
            LoadRecentImages();
        }

        protected abstract void LoadBuiltInImages();

        protected void LoadRecentImages()
        {
            FileInfo[] recentImages = Helper.FindFilesInDirectory(this.RecentImagesDir, format);
            Array.Sort(recentImages, new FileInfoComparer());

            int count = 0;
            foreach (FileInfo imageFileName in recentImages)
            {
                ++count;
                string fileName = imageFileName.FullName;
                Image image = Image.FromFile(fileName);
                string tooltip = Helper.GetImageInfo(image);
                this.Items.Add(
                new Elegant.Ui.GalleryItem(fileName, image, null,
                        tooltip, RecentCategory.Name)
                );

                if (count == maxRecentImageFilesCount)
                {
                    break;
                }
            }
        }

        private void AddImage(string path)
        {
            GalleryItem item = null;

            if (File.Exists(path))
            {
                //remove last historical item if the historical category is full
                if (RecentImagesCount == maxRecentImageFilesCount)
                {
                    for(int i = this.Items.Count - 1; i >= 0; --i)
                    {
                        GalleryItem galleryItem = (GalleryItem)this.Items[i];
                        if (galleryItem.CategoryName == RecentCategory.Name)
                        {
                            this.Items.RemoveAt(i);
                            break;
                        }
                    }
                }

                Image image = Image.FromFile(path);
                string savePath = this.RecentImagesDir + Guid.NewGuid() + Path.GetExtension(path);
                if (!File.Exists(savePath))
                {
                    image.Save(savePath);
                }

                string tooltip = Helper.GetImageInfo(image);
                item = new GalleryItem(savePath,
                image, null, tooltip, RecentCategory.Name);
                this.Items.Insert(0, item);
                this.SelectedItem = item;
                this.EnsureItemVisible(item);
            }
        }

        private void BrowseImagesButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog fileOpenDlg = Helper.CreateOpenFileDialog(format, false);
            fileOpenDlg.InitialDirectory = Helper.MyPicturesDir;
            if (fileOpenDlg.ShowDialog() == DialogResult.OK)
            {
                string fileName = fileOpenDlg.FileName;
                AddImage(fileName);
            }
        }

        private System.Drawing.Image ExtractImageFromItem(object item)
        {
            if (item == null || !(item is GalleryItem))
            {
                return null;
            }

            GalleryItem galleryItem = item as GalleryItem;
            return galleryItem.Image;
        }

        public void SetSelectedImage(string imageFilePath)
        {
            foreach (GalleryItem item in Items)
            {
                string itemPath = (string)item.Data;
                if (itemPath.Equals(imageFilePath, StringComparison.OrdinalIgnoreCase))
                {
                    this.SelectedItem = item;
                    this.EnsureItemVisible(item);
                    return;
                }
            }

            AddImage(imageFilePath);
        }

        #endregion
    }
}
